package pl.edu.pw.perg.compinfodb.datamodel;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultTreeModel;

import pl.edu.pw.perg.compinfodb.entities.VirtualElement;
import pl.edu.pw.perg.compinfodb.manager.IVirtualElementManager;

@SuppressWarnings("serial")
public class StructureTreeModel extends DefaultTreeModel implements TreeSelectionListener{

//  private IVirtualElementManager elementManager;
  private VirtualElement selectedElement;
  private List<IStructureTreeSelectionListener> listeners = new ArrayList<IStructureTreeSelectionListener>();
  
  
  public StructureTreeModel(IVirtualElementManager elementManager) {
    super(getStructureTree(elementManager));
    
    
  }
  
  private static SelectableTreeNode createTree(VirtualElement elt) {
    SelectableTreeNode rootNode = new SelectableTreeNode(elt);
    Collection<VirtualElement> children = elt.getChildren();
    for (Iterator<VirtualElement> i = children.iterator(); i.hasNext();) {
      VirtualElement child = (VirtualElement) i.next();
      rootNode.add(createTree(child));
    }
    return rootNode;

  }
  private static SelectableTreeNode getStructureTree(IVirtualElementManager elementManager){
    SelectableTreeNode rootNode = new SelectableTreeNode("CMS Experiment");
    List<VirtualElement> elements = elementManager.findRoots();
    Collections.sort(elements);
    for (Iterator<VirtualElement> i = elements.iterator(); i.hasNext();) {
      VirtualElement elt = (VirtualElement) i.next();
      SelectableTreeNode eltNode = createTree(elt);
      rootNode.add(eltNode);
    }
    return rootNode;
  }
  
  public void displayElementBranch(VirtualElement ve){
    SelectableTreeNode node = (SelectableTreeNode) findNodeWithValue((SelectableTreeNode) 
        getRoot(), ve);
    for(Enumeration<SelectableTreeNode> e = node.getParent().children(); 
      e.hasMoreElements();){
      SelectableTreeNode child = e.nextElement();
      if(child.equals(node))
        continue;
      child.setVisible(false);
    }
      
    
  }
  
  private SelectableTreeNode findNodeWithValue(SelectableTreeNode root, Object value){
    if(root.getUserObject() != null && root.getUserObject().equals(value))
      return root;
    SelectableTreeNode child = null; 
    for(Enumeration<SelectableTreeNode> e = root.children(); e.hasMoreElements();){
      child = e.nextElement();
      SelectableTreeNode found = findNodeWithValue(child, value);
        if(found != null)
          return found; 
    }
    return null;
  }

  public VirtualElement getSelectedElement() {
    return selectedElement;
  }

  public void setSelectedElement(VirtualElement selectedElement) {
    this.selectedElement = selectedElement;
  }
  
  public void addSelectionListener(IStructureTreeSelectionListener l) {
    listeners.add(l);
  }

  public void valueChanged(TreeSelectionEvent e) {
    SelectableTreeNode selectedNode = (SelectableTreeNode) ((JTree) e.getSource()).
      getLastSelectedPathComponent();
    if(selectedNode == null)
    	return;
    Object element = selectedNode.getUserObject();
    if (element instanceof VirtualElement) 
		selectedElement = (VirtualElement) element;		
    for (IStructureTreeSelectionListener l : listeners) {
      l.selectionChanged(selectedElement);
    }
  }
  
  

  
}
